package com.et114.components.acegi.acl.creator;

import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.acl.basic.AclObjectIdentity;
import org.acegisecurity.acl.basic.BasicAclExtendedDao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import com.et114.components.acegi.acl.AclCreator;

/**
 * 为创建acl信息提供了抽象的实现，仅仅提供了一些属性。
 *
 * @author guanhw
 * @see SimpleAclCreator
 * @see DroolsRuleAclCreator
 */
public abstract class AbstractBasicAclCreator implements AclCreator {

    protected Log					logger	= LogFactory.getLog( getClass() );

	protected BasicAclExtendedDao	aclDAO;
	protected Class					processDomainObjectClass;
	protected Class					processReturnedObjectClass;
	protected Class					defaultAclObjectIdentityClass;

	public Class getProcessReturnedObjectClass ( ) {
		return processReturnedObjectClass;
	}

	/**
	 * 什么样的返回类型需要处理，可为空
	 *
	 * @param processReturnedObjectClass
	 */
	public void setProcessReturnedObjectClass ( Class processReturnedObjectClass ) {
		this.processReturnedObjectClass = processReturnedObjectClass;
	}

	public Class getDefaultAclObjectIdentityClass ( ) {
		return defaultAclObjectIdentityClass;
	}

	/**
	 * 默认的AclObjectIdentity
	 * @param defaultAclObjectIdentityClass
	 */
	public void setDefaultAclObjectIdentityClass (
			Class defaultAclObjectIdentityClass ) {
		this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass;
	}

	public Class getProcessDomainObjectClass ( ) {
		return processDomainObjectClass;
	}

	/**
	 * 什么样的domainClass需要处理
	 *
	 * @param processDomainObjectClass
	 */
	public void setProcessDomainObjectClass ( Class processDomainObjectClass ) {
		this.processDomainObjectClass = processDomainObjectClass;
	}

	public BasicAclExtendedDao getAclDAO ( ) {
		return aclDAO;
	}

	public void setAclDAO ( BasicAclExtendedDao aclDAO ) {
		this.aclDAO = aclDAO;
	}

	public void afterPropertiesSet ( ) {
		Assert.notNull( aclDAO, "basicAclDao required" );
		Assert.notNull( processDomainObjectClass ,"processDomainObjectClass required" );
		Assert.notNull( defaultAclObjectIdentityClass , "defaultAclObjectIdentityClass required" );
		Assert.isTrue( AclObjectIdentity.class .isAssignableFrom( this.defaultAclObjectIdentityClass ),
						"defaultAclObjectIdentityClass must implement AclObjectIdentity" );
		try {
			defaultAclObjectIdentityClass .getConstructor( new Class [ ] { Object.class } );
		} catch ( NoSuchMethodException nsme ) {
			throw new IllegalArgumentException(
					"defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!" );
		}
	}

	public abstract void creat ( Authentication authentication , Object object ,
			ConfigAttributeDefinition config , Object returnedObject )
			throws AccessDeniedException;

	public boolean supports ( ConfigAttribute attribute ) {
		return true;
	}

	public boolean supports ( Class clazz ) {
		return true;
	}

	public boolean supports ( Object domainObject , Object returnedObject ) {
		return true;
	}
}
